package com.gxks.lhs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxks.lhs.entity.User;
import com.gxks.lhs.mapper.UserMapper;
import com.gxks.lhs.service.IGoodsService;
import com.gxks.lhs.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

import static com.gxks.lhs.constants.Constants.USER_BLOCK;
import static com.gxks.lhs.constants.Constants.USER_NORMAL;
import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author LuoHaisong
 * @since 2023-05-18
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private IGoodsService goodsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean banUser(String userId) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", userId);
        updateWrapper.set("status", USER_BLOCK);
        //下架用户的所有二手手机
        goodsService.updateGoodsStatusByUserId(userId, 0);
        return this.update(updateWrapper);
    }

    @Override
    public boolean updateUser(User user) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id", user.getId())
                .set(user.getAvatar() != null, "avatar", user.getAvatar())
                .set(user.getNickname() != null, "nickname", user.getNickname())
                .set(user.getEmail() != null, "email", user.getEmail())
                .set(user.getPhone() != null, "phone", user.getPhone())
                .set(user.getRemarks() != null, "remarks", user.getRemarks());
        return this.update(updateWrapper);
    }

    @Override
    public Page<User> findAllUsers(Integer current, Integer size) {
        return this.page(new Page<>(current, size));
    }

    @Override
    public Page<User> findUsersByCondition(User user, Integer current, Integer size) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(user.getId() != null, "id", user.getId())
                .like(user.getStatus() != null, "status", user.getStatus())
                .like(user.getEmail() != null, "email", user.getEmail())
                .like(user.getNickname() != null, "nickname", user.getNickname())
                .like(user.getUsername() != null, "username", user.getUsername())
                .like(user.getPhone() != null, "phone", user.getPhone());
        return this.page(new Page<>(current, size), queryWrapper);
    }


    @Override
    public User getUserById(String id) {
        return this.getById(id);
    }

    @Override
    public boolean unseal(Integer userId) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", userId);
        updateWrapper.set("status", USER_NORMAL);
        return this.update(updateWrapper);
    }

    @Override
    public User getUserByUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return this.getOne(queryWrapper);
    }

    @Override
    public boolean addUser(User user) {
        return this.save(user);
    }

    @Override
    public boolean deleteUser(String userId) {
        log.info("用户注销账户，用户id:{}", userId);
        User user = getById(userId);
        //判断用户余额是否大于0。若大于0，则不能删除。
        if (user.getBalance().compareTo(BigDecimal.ZERO) > 0) {
            return false;
        }
        return this.removeById(userId);
    }

    @Override
    public User getUserByPhone(String phone) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        return this.getOne(queryWrapper);
    }

    @Override
    public boolean isExist(String phone) {
        return this.getUserByPhone(phone) != null;
    }

    @Override
    public String getPhoneByUserId(String userId) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(User::getPhone).eq(User::getId, userId);
        return this.getOne(lambdaQueryWrapper).getPhone();
    }

    @Override
    public BigDecimal getBalanceByUserId(String userId) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(User::getBalance).eq(User::getId, userId);
        User user = this.getOne(lambdaQueryWrapper);
        return user.getBalance();
    }

//    @Override
//    public boolean withdraw(String userId, String amount) {
//        if (this.getBalanceByUserId(userId).compareTo(amount) < 0) {
//            return false;
//        }
//
//        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        lambdaUpdateWrapper.eq(User::getId, userId)
//                .setSql("balance = balance - " + amount);
//        return this.update(lambdaUpdateWrapper);
//    }


    /**
     * 用户提现操作。
     *
     * @param userId         用户ID。
     * @param withdrawAmount 提现金额。
     * @return 如果操作成功（余额充足且更新成功），返回true；否则返回false。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean withdraw(String userId, BigDecimal withdrawAmount) {
        // 验证余额是否充足
        BigDecimal balance = this.getBalanceByUserId(userId);
        if (balance.compareTo(withdrawAmount) < 0) {
            return false;
        }
        //打款
        log.info("用户{}提现{}元", userId, withdrawAmount);
        // 计算提后余额
        BigDecimal newBalance = balance.subtract(withdrawAmount);

        // 构建更新用户余额的查询条件
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, userId);
        lambdaUpdateWrapper.set(User::getBalance, newBalance);
        // 执行更新操作并返回结果
        return this.update(lambdaUpdateWrapper);
    }

    @Override
    public boolean balancePay(String userId, BigDecimal amount) {
        // 验证余额是否充足
        BigDecimal balance = this.getBalanceByUserId(userId);
        if (balance.compareTo(amount) < 0) {
            return false;
        }
        //打款
        log.info("用户{}余额支出{}元", userId, amount);
        // 计算提后余额
        BigDecimal newBalance = balance.subtract(amount);

        // 构建更新用户余额的查询条件
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, userId);
        lambdaUpdateWrapper.set(User::getBalance, newBalance);
        // 执行更新操作并返回结果
        return this.update(lambdaUpdateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean recharge(String userId, BigDecimal withdrawAmount) {
        // 获取用户余额
        BigDecimal balance = this.getBalanceByUserId(userId);
        //打款
        log.info("用户{}充值{}元", userId, withdrawAmount);
        // 计算提后余额
        BigDecimal newBalance = balance.add(withdrawAmount);

        if (newBalance.compareTo(BigDecimal.ZERO) < 0) {
            return false;
        }

        // 构建更新用户余额的查询条件
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, userId);
        lambdaUpdateWrapper.set(User::getBalance, newBalance);
        // 执行更新操作并返回结果
        return this.update(lambdaUpdateWrapper);
    }

    @Override
    public boolean IsBan(String userId) {
        return this.getUserById(userId).getStatus() == USER_BLOCK;
    }

    @Override
    public boolean updateUserPassword(User user) {
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, user.getId())
                .set(User::getPassword, user.getPassword());
        return this.update(lambdaUpdateWrapper);
    }
}
